#include "teststdafx.h"
#include "stdafx.h"
#include <gtest/gtest.h>

using namespace std;

#include "Business/Dealing.h"
#include "Business/Customer.h"

class DealingTest : public testing::Test
{
protected:
	DealingTest():m_customer("","",""){}

	virtual void SetUp()
	{
	}

	virtual void TearDown()
	{

	}
	Customer m_customer;
};

Order CreateOrder(double price, int quantity)
{
	Order order = {0};
	order.contract = 0;
	order.direction = Direction::BUY;
	order.operation = Operation::OPEN;
	order.price = price;
	order.quantity = quantity;

	return order;
}

TEST_F(DealingTest,SendFailedTest)
//void foo()
{
	Order orderInfo = CreateOrder(1000,10);
	Dealing dealing(m_customer,orderInfo);

	dealing.OnSendFailed();

	EXPECT_EQ(true, dealing.IsSendFailed());
	
};

TEST_F(DealingTest,SomeTest)
//void foo()
{
	Order orderInfo = CreateOrder(1000.00,10);
	Dealing dealing(m_customer,orderInfo);

	dealing.OnAccept();
	EXPECT_EQ(true, dealing.IsAccept());

	string systemNo = "system_no";
	dealing.OnOrdered(systemNo.c_str());
	EXPECT_EQ(true,dealing.IsOrdered());
	EXPECT_EQ(systemNo,dealing.GetSystemNo());

	Trade trade(dealing,910.00,4,systemNo.c_str());

	dealing.OnTrade(trade);
	EXPECT_EQ(true,dealing.IsPartial());
	EXPECT_EQ(trade.GetDealQuantity(), dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(trade.GetDealPrice(), dealing.GetAverageDealPrice());
	EXPECT_EQ(6, dealing.GetRemainQuantity());

	Trade trade2(dealing,822,3,systemNo.c_str());

	double expectedPrice = (910.00*4+822.00*3)/7;
	dealing.OnTrade(trade2);
	EXPECT_EQ(true,dealing.IsPartial());
	EXPECT_EQ(7, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(3, dealing.GetRemainQuantity());

	Trade trade3(dealing,821.00,3,systemNo.c_str());

	expectedPrice = (910.00*4+822.00*3+821.00*3)/10;
	dealing.OnTrade(trade3);
	EXPECT_EQ(true,dealing.IsComplete());
	EXPECT_EQ(10, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(0, dealing.GetRemainQuantity());

	dealing.OnCancelSendFailed();
	EXPECT_EQ(true,dealing.IsComplete());
	EXPECT_EQ(10, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(0, dealing.GetRemainQuantity());

};


TEST_F(DealingTest,CancelTest)
//void foo()
{
	Order orderInfo = CreateOrder(1000.00,10);
	Dealing dealing(m_customer,orderInfo);

	dealing.OnAccept();
	EXPECT_EQ(true, dealing.IsAccept());

	string systemNo = "system_no";
	dealing.OnOrdered(systemNo.c_str());
	EXPECT_EQ(true,dealing.IsOrdered());
	EXPECT_EQ(systemNo,dealing.GetSystemNo());

	Trade trade(dealing,910.00,4,systemNo.c_str());

	dealing.OnTrade(trade);
	EXPECT_EQ(true,dealing.IsPartial());
	EXPECT_EQ(trade.GetDealQuantity(), dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(trade.GetDealPrice(), dealing.GetAverageDealPrice());
	EXPECT_EQ(6, dealing.GetRemainQuantity());
	EXPECT_EQ(0,dealing.GetCancelQuantity());


	Trade trade2(dealing,822.00,3,systemNo.c_str());
	
	double expectedPrice = (910.00*4+822.00*3)/7;
	dealing.OnTrade(trade2);
	EXPECT_EQ(true,dealing.IsPartial());
	EXPECT_EQ(7, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(3, dealing.GetRemainQuantity());
	EXPECT_EQ(0,dealing.GetCancelQuantity());

	dealing.OnCancelSendFailed();
	EXPECT_EQ(true,dealing.IsCancelSendFailed());
	EXPECT_EQ(7, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(3, dealing.GetRemainQuantity());
	EXPECT_EQ(0,dealing.GetCancelQuantity());

	dealing.OnCancelSuccess(7);
	EXPECT_EQ(true,dealing.IsCanceled());
	EXPECT_EQ(7, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(0, dealing.GetRemainQuantity());
	EXPECT_EQ(3,dealing.GetCancelQuantity());

}

TEST_F(DealingTest,CancelBeforeTradeTest)
//void foo()
{
	Order orderInfo = CreateOrder(1000.00,10);
	Dealing dealing(m_customer,orderInfo);

	dealing.OnAccept();
	EXPECT_EQ(true, dealing.IsAccept());

	string systemNo = "system_no";
	dealing.OnOrdered(systemNo.c_str());
	EXPECT_EQ(true,dealing.IsOrdered());
	EXPECT_EQ(systemNo,dealing.GetSystemNo());

	Trade trade(dealing,910.00,4,systemNo.c_str());

	dealing.OnTrade(trade);
	EXPECT_EQ(true,dealing.IsPartial());
	EXPECT_EQ(trade.GetDealQuantity(), dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(trade.GetDealPrice(), dealing.GetAverageDealPrice());
	EXPECT_EQ(6, dealing.GetRemainQuantity());
	EXPECT_EQ(0,dealing.GetCancelQuantity());


	Trade trade2(dealing,822.00,3,systemNo.c_str());

	double expectedPrice = (910.00*4+822.00*3)/7;
	dealing.OnTrade(trade2);
	EXPECT_EQ(true,dealing.IsPartial());
	EXPECT_EQ(7, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(3, dealing.GetRemainQuantity());
	EXPECT_EQ(0,dealing.GetCancelQuantity());

	dealing.OnCancelSuccess(9);
	EXPECT_EQ(false,dealing.IsCanceled());
	EXPECT_EQ(true,dealing.IsWaitTrade());
	EXPECT_EQ(7, dealing.GetDealQuantity());
	EXPECT_EQ(0, dealing.GetRemainQuantity());
	EXPECT_EQ(1,dealing.GetCancelQuantity());

	Trade trade3(dealing,822.00,2,systemNo.c_str());
	expectedPrice = (910.00*4+822.00*5)/9;
	dealing.OnTrade(trade3);
	EXPECT_EQ(true,dealing.IsCanceled());
	EXPECT_EQ(false,dealing.IsWaitTrade());
	EXPECT_EQ(9, dealing.GetDealQuantity());
	EXPECT_DOUBLE_EQ(expectedPrice, dealing.GetAverageDealPrice());
	EXPECT_EQ(0, dealing.GetRemainQuantity());
	EXPECT_EQ(1,dealing.GetCancelQuantity());
};



